package com.zlll.winner.service.mall.async;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zlll.winner.business.model.mall.MallGoodsDetails;
import com.zlll.winner.business.model.mall.MallSeckillGoods;
import com.zlll.winner.business.model.mall.MallSelectGoods;
import com.zlll.winner.business.service.mall.IMallGoodsDetailsService;
import com.zlll.winner.business.service.mall.IMallSeckillGoodsService;
import com.zlll.winner.business.service.mall.IMallSelectGoodsService;
import com.zlll.winner.mapper.mall.MallGoodsDetailsMapper;
import com.zlll.winner.mapper.mall.MallSeckillGoodsMapper;
import com.zlll.winner.mapper.mall.MallSelectGoodsMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Service
@Async
@Slf4j
public class MallOrderAsuncService {

    @Resource
    private MallGoodsDetailsMapper mallGoodsDetailsMapper;
    @Resource
    private MallSeckillGoodsMapper mallSeckillGoodsMapper;
    @Resource
    private MallSelectGoodsMapper mallSelectGoodsMapper;

    /**
     * 减少库存
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int subtract(Integer source , Long sourceId,Long  gooodsId,Integer num){
        Long time = System.currentTimeMillis();
        Integer result = 0;
        MallGoodsDetails goodsDetails = mallGoodsDetailsMapper.selectById(gooodsId);
        Long oldTime = goodsDetails.getUpdateTime();
        goodsDetails.setInventoryNum(goodsDetails.getInventoryNum()-num);
        goodsDetails.setSalesNum(goodsDetails.getSalesNum()+num);
        goodsDetails.setUpdateTime(time);
        result = mallGoodsDetailsMapper.update(goodsDetails, Wrappers.<MallGoodsDetails>lambdaQuery()
                .eq(MallGoodsDetails::getId,gooodsId).eq(MallGoodsDetails::getUpdateTime,oldTime));
        if(result == 0){
            return result;
        }
        if(source.equals(1)){
            MallSeckillGoods mallSeckillGoods = mallSeckillGoodsMapper.selectById(sourceId);
             oldTime = mallSeckillGoods.getUpdateTime();
            mallSeckillGoods.setConvertedNum(mallSeckillGoods.getConvertedNum()+num);
            mallSeckillGoods.setUpdateTime(time);
            result += mallSeckillGoodsMapper.update(mallSeckillGoods,Wrappers.<MallSeckillGoods>lambdaQuery()
                    .eq(MallSeckillGoods::getId,sourceId).eq(MallSeckillGoods::getUpdateTime,oldTime));

            if(result != 2){
                return 0;
            }
        }else{
            MallSelectGoods mallSelectGoods = mallSelectGoodsMapper.selectById(sourceId);
            oldTime = mallSelectGoods.getUpdateTime();
            mallSelectGoods.setConvertedNum(mallSelectGoods.getConvertedNum()+num);
            mallSelectGoods.setUpdateTime(time);
            result += mallSelectGoodsMapper.update(mallSelectGoods,Wrappers.<MallSelectGoods>lambdaQuery()
                    .eq(MallSelectGoods::getId,sourceId).eq(MallSelectGoods::getUpdateTime,oldTime));
            if(result != 2){
                return 0;
            }
        }
        return result;
    }

    /**
     * 异步减少库存
     * @param source
     * @param sourceId
     * @param gooodsId
     * @param num
     * @throws InterruptedException
     */
    @Async
    public void subtractInventoryNum(Integer source , Long sourceId,Long  gooodsId,Integer num)  throws InterruptedException{
        int res = 0;
        int sum = 10;
        while (res == 0 && sum > 0) {
            res = subtract( source ,  sourceId,  gooodsId, num);
            if (res == 0) Thread.sleep(500L);
            sum--;
        }
        log.error("减少库存完毕。");
    }



    /**
     * 减少库存
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    public int increase(Integer source , Long sourceId,Long  gooodsId,Integer num){
        Long time = System.currentTimeMillis();
        MallGoodsDetails goodsDetails = mallGoodsDetailsMapper.selectById(gooodsId);
        Long oldTime = goodsDetails.getUpdateTime();
        goodsDetails.setInventoryNum(goodsDetails.getInventoryNum()+num);
        goodsDetails.setSalesNum(goodsDetails.getSalesNum()-num);
        goodsDetails.setUpdateTime(time);
        Integer result = mallGoodsDetailsMapper.update(goodsDetails, Wrappers.<MallGoodsDetails>lambdaQuery()
                .eq(MallGoodsDetails::getId,gooodsId).eq(MallGoodsDetails::getUpdateTime,oldTime));
        if(result == 0){
            return result;
        }
        if(source.equals(1)){
            MallSeckillGoods mallSeckillGoods = mallSeckillGoodsMapper.selectById(sourceId);
            oldTime = mallSeckillGoods.getUpdateTime();
            mallSeckillGoods.setConvertedNum(mallSeckillGoods.getConvertedNum()-1);
            mallSeckillGoods.setUpdateTime(time);
            result += mallSeckillGoodsMapper.update(mallSeckillGoods,Wrappers.<MallSeckillGoods>lambdaQuery()
                    .eq(MallSeckillGoods::getId,sourceId).eq(MallSeckillGoods::getUpdateTime,oldTime));

            if(result != 2){
                return 0;
            }
        }else{
            MallSelectGoods mallSelectGoods = mallSelectGoodsMapper.selectById(sourceId);
            oldTime = mallSelectGoods.getUpdateTime();
            mallSelectGoods.setConvertedNum(mallSelectGoods.getConvertedNum()-num);
            mallSelectGoods.setUpdateTime(time);
            result += mallSelectGoodsMapper.update(mallSelectGoods,Wrappers.<MallSelectGoods>lambdaQuery()
                    .eq(MallSelectGoods::getId,sourceId).eq(MallSelectGoods::getUpdateTime,oldTime));
            if(result != 2){
                return 0;
            }
        }
        return result;
    }

    /**
     * 增加减少库存
     * @param source
     * @param sourceId
     * @param gooodsId
     * @param num
     * @throws InterruptedException
     */
    @Async
    public void increaseInventoryNum(Integer source , Long sourceId,Long  gooodsId,Integer num)  throws InterruptedException{
        int res = 0;
        int sum = 10;
        while (res == 0 && sum > 0) {
            res = increase( source ,  sourceId,  gooodsId, num);
            if (res == 0) Thread.sleep(500L);
            sum--;
        }
        log.error("增加库存完毕。");
    }


}
